<?php

use models\Business\Address;
use models\Business\Booking;
use models\Business\Coupon;
use models\Business\Order;
use models\Business\Member;
use models\Exception\Business\AlibabaproductException;
use models\Exception\Business\BookingException;
use models\Exception\Business\MemberException;
use Yaf\Registry;
use models\Business\AliPay;
use youliPhpLib\Common\PwdAss;
use models\Business\AlibabaProduct;

class CouponController extends ApiBaseController
{
    /**
     * @SWG\Post(
     *     path="/v3/order/shippingfee",
     *     tags={"订单模块"},
     *     summary="获取运费",
     *     description="
     * product_id 必须参数 商品编号 v3/alibabaproduct/list接口返回的id字段
     * address_id 非必须参数 收货地址 若不存在，则将当前用户的默认地址作为收货地址
     * num 非必须参数 商品数量 若不存在，商品数量按照一件来计算",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="201",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="422",
     *         description="创建失败"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function shippingFeeAction() {
        $parameters = Registry::get('parameters');

        if (! isset($parameters['address_id']) || empty($parameters['address_id'])) {
            $address = Address::getAddressList([
                'is_default' => 1,
                'member_id' => Registry::get('jwt_info')->id,
                'from_api'  => $parameters['from_api']
            ]);
        } else {
            // 校验收货地址
            $address = Address::getAddressList([
                'id'        => $parameters['address_id'],
                'member_id' => Registry::get('jwt_info')->id,
                'from_api'  => $parameters['from_api']
            ]);
        }

        $shipping = AlibabaProduct::getShippingFeeByProductIdProvince(
            $parameters['product_id'], $address['data'][0]['province'], isset($parameters['num']) && !empty($parameters['num']) ? $parameters['num'] : 1);

        return $this->_responseJson($shipping);
    }

    /**
     * @SWG\Get(
     *     path="/v3/order/paytype",
     *     tags={"订单模块"},
     *     summary="获取支付方式",
     *     description="
     * page 必须参数 页码  固定值:1
     * page_size 必须参数 每页显示条数 固定值:999
     * sort 必须参数 排序方式 可选值:desc降序、asc生序
     * order 必须参数 排序字段 固定值:id",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值 该参数在获取商品详情页的'他们正在拼'时才允许不传，其他时候必须",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="签名",
     *          in="query",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="200",
     *         description="请求成功",
     *         @SWG\Schema(type="object", ref="#/definitions/orderListData")
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function payTypeAction() {
        $parameters = Registry::get('parameters');
        $pay_type_list = ['data' => [
            [
                'id' => 0,
                'name' => '支付宝支付'
            ],
//            [
//                'id' => 1,
//                'name' => '微信支付'
//            ],
            [
                'id' => 2,
                'name' => '余额支付'
            ]
        ]];
        if ($parameters['sort'] == 'desc')
            array_multisort(array_column($pay_type_list['data'], 'id'), SORT_DESC, $pay_type_list['data']);
        else
            array_multisort(array_column($pay_type_list['data'], 'id'), SORT_ASC, $pay_type_list['data']);

        return $this->_responseJson($pay_type_list);
    }

    /**
     * @SWG\Post(
     *     path="/v3/order/order",
     *     tags={"订单模块"},
     *     summary="拼团下单",
     *     description="
     * product_id 必须参数 商品编号 v3/alibabaproduct/list接口返回的id字段
     * num 必须参数 商品数量,如多样式商品，用','隔开：1,2;必须和sku_id对应
     * sku_id 非必须参数 ,如多样式商品，用','隔开:4301185405556,4301185405557",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="201",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="422",
     *         description="创建失败"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function orderAction()
    {
        $product_id = Registry::get('parameters')['product_id'];
        $member_id  = Registry::get('jwt_info')->id;
        $number        = Registry::get('parameters')['num'];
        $sku_id     = isset(Registry::get('parameters')['sku_id']) ? Registry::get('parameters')['sku_id'] : '';

        $sku_id_arr = explode(',', $sku_id);
        $num_arr = explode(',', $number);

        if (count($sku_id_arr) != 0 && count($num_arr) !== count($sku_id_arr))
            throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_NUM_PRODUCT_NOT_EXISTS, AlibabaproductException::ALIBABAPRODUCT_NUM_PRODUCT_NOT_EXISTS_NO);

        $coupon = null;
        $ali_store = false;
        foreach ($num_arr as $idx => $num) {
            if (is_null($coupon))
                    $coupon = new Coupon($product_id, $num, $member_id, $sku_id_arr[$idx]);
            else {
                if (isset($sku_id_arr[$idx])) {
                    $coupon->setNum($num);
                    $coupon->setSkuId($sku_id_arr[$idx]);
                }
            }

            // 检测本地库存是否有效
            $coupon->checkStore();

            // 校验当前用户是否允许发起拼团
            $coupon->memberCouponIsValid();

            // 调用1688接口，校验商品库存
            if ($idx == 0)
                $ali_store = $coupon->checkStoreFromAlibaba(array_sum($num_arr));
            if ($ali_store !== true)
                // 商品不存在于1688接口 将数据库中指定商品的stats调整为0
                $coupon->invalidAlibabaProduct();

            // 更新数据库中 指定商品的库存与最小起订量发生
            $coupon->updateAlibabaProduct();
            // 更新数据库中 指定sku的库存
            $coupon->updateAlibabaProductSku();

            // 事务 更新数据库
            $coupon->updateDb();

            // 用户所购买的商品数量不满足最低起订数
            if (is_string($ali_store))
                throw new AlibabaproductException($ali_store, 400);

            // 扣除redis中的商品库存
            $coupon->decrStoreByProductId();

            if ($ali_store === false)
                throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_INVALID_STORE, AlibabaproductException::ALIBABAPRODUCT_INVALID_STORE_NO);

        }

        // 校验收货地址
        $address = Address::getAddressList([
            'is_default' => 1,
            'member_id' => Registry::get('jwt_info')->id,
            'from_api'  => true
        ]);

        // 创建拼团所需的支付信息写入redis
        $booking_data = $coupon->getBookingData($sku_id, $number, $address['data'][0]['province'], $address['data'][0]['id']);

        $coupon->closeRedis();

        // 拼团所需的支付信息写入数据库
        Booking::createBooking($booking_data);

        return $this->_responseJson($booking_data);
    }

    /**
     * @SWG\Post(
     *     path="/v3/order/prepay",
     *     tags={"订单模块"},
     *     summary="预支付接口",
     *     description="
     * sn 必须参数 预支付订单号 order/order返回的sn
     * product_id 必须参数 商品编号 v3/alibabaproduct/list接口返回的id字段
     * num 必须参数 商品数量
     * channel 必须参数 支付渠道 order/paytype接口返回的id
     * address_id 必须参数 收货地址 address/list接口返回的id
     * sku_id 非必须参数 sku_id
     * is_wap 非必须参数 前端调用该接口时必须，固定值：1
     * paypassword 非必须参数 余额支付时必须",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="201",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="422",
     *         description="创建失败"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function prePayAction()
    {
        // 拼团 预支付接口
        $parameters = Registry::get('parameters');

        //验证支付密码
        if ($parameters['channel'] == 2) {
            if (! isset($parameters['paypassword']))
                throw new MemberException(MemberException::MEMBER_PASSWORD_EMPTY, MemberException::MEMBER_PASSWORD_EMPTY_NO);
            $member=Member::getMemberInfoById(Registry::get('jwt_info')->id);

            if(!isset($member['pay_password'])||empty($member['pay_password'])){
                throw new MemberException(MemberException::MEMBER_PAY_PASSWORD_EMPTY, MemberException::MEMBER_PAY_PASSWORD_EMPTY_NO);
            }
            if (PwdAss::getInstance(8, true)->CheckPassword($parameters['paypassword'], $member['pay_password']) === false)
                throw new MemberException(MemberException::WRONG_PASSWORD, MemberException::WRONG_PASSWORD_NO);
        }

        // 校验收货地址
        Address::getAddressList([
            'id'        => $parameters['address_id'],
            'member_id' => Registry::get('jwt_info')->id,
            'from_api'  => $parameters['from_api']
        ]);

        $product_id = Registry::get('parameters')['product_id'];
        $member_id  = Registry::get('jwt_info')->id;
        $number     = Registry::get('parameters')['num'];
        $sku_id     = isset(Registry::get('parameters')['sku_id']) ? Registry::get('parameters')['sku_id'] : '';

        $sku_id_arr = explode(',', $sku_id);
        $num_arr = explode(',', $number);

        if (count($sku_id_arr) != 0 && count($num_arr) !== count($sku_id_arr))
            throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_NUM_PRODUCT_NOT_EXISTS, AlibabaproductException::ALIBABAPRODUCT_NUM_PRODUCT_NOT_EXISTS_NO);

        $coupon = null;
        $ali_store = false;
        foreach ($num_arr as $idx => $num) {
            if (is_null($coupon))
                $coupon = new Coupon($product_id, $num, $member_id, $sku_id_arr[$idx]);
            else {
                if (isset($sku_id_arr[$idx])) {
                    $coupon->setNum($num);
                    $coupon->setSkuId($sku_id_arr[$idx]);
                }
            }

            // 检测本地库存是否有效
            $coupon->checkStore();

            // 校验当前用户是否允许发起拼团
//            $coupon->memberCouponIsValid();

            // 调用1688接口，校验商品库存
            if ($idx == 0)
                $ali_store = $coupon->checkStoreFromAlibaba(array_sum($num_arr));
            if ($ali_store !== true)
                // 商品不存在于1688接口 将数据库中指定商品的stats调整为0
                $coupon->invalidAlibabaProduct();

            if ($ali_store === false)
                throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_INVALID_STORE, AlibabaproductException::ALIBABAPRODUCT_INVALID_STORE_NO);

        }
        // 创建拼团所需的支付信息写入redis
//        $coupon->setSkuId($sku_id);
//        $coupon->setNum($number);

        $booking_data = $coupon->getBookingDataFromRedis($parameters['sn'], $parameters['address_id'], $parameters['channel']);

        // 拼团所需的支付信息写入数据库
        $booking = Booking::editBooking($booking_data);

        // 余额支付
        if ($booking['channel'] == 2) {
            $booking['amount'] = $booking['price'] /*+ $booking['fee']*/;
            Order::createOrderByBalance($booking);
        }
        if (isset($parameters['is_wap']) && $parameters['is_wap'] == 1 && $booking['channel'] != 2) {
            // 读取商品数据
            $coupon->getProductInfoFromLocal();
            $product_info = $coupon->getProductFromLocal();
            $booking['title'] = $product_info['title'];
            $pay_url = AliPay::alipayWapPay($booking);
            $booking['pay_url'] = $pay_url;
        } else if ($booking['channel'] != 2) {
            // 读取商品数据
            $coupon->getProductInfoFromLocal();
            $product_info = $coupon->getProductFromLocal();
            $booking['title'] = $product_info['title'];
            $pay_url = AliPay::alipayTradeAppPay($booking);
            $booking['pay_url'] = $pay_url;
        }

        return $this->_responseJson($booking);
    }

    /**
     * @SWG\Post(
     *     path="/v3/order/integralOrder",
     *     tags={"订单模块"},
     *     summary="金币兑换商品下单",
     *     description="
     * product_id 必须参数 商品编号 v3/alibabaproduct/list接口返回的id字段
     * num 必须参数 商品数量,如多样式商品，用','隔开：1,2;必须和sku_id对应
     * address_id 必须参数 收货地址
     * sku_id 非必须参数 sku_id,如多样式商品，用','隔开:4301185405556,4301185405557",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="201",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="422",
     *         description="创建失败"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function integralOrderAction()
    {
        // 金豆买商品
        $parameters = Registry::get('parameters');

        //校验数量
        if (empty($parameters['num']))
            throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_NUM_NOT_EXISTS, AlibabaproductException::ALIBABAPRODUCT_NUM_NOT_EXISTS_NO);
        //校验数量和sku_id
        $num_arr = explode(',', $parameters['num']);
        $sku_id_arr = explode(',', $parameters['sku_id']);

        if (count($sku_id_arr) > 1 && count($num_arr) != count($sku_id_arr)) {
            throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_NUM_PRODUCT_NOT_EXISTS, AlibabaproductException::ALIBABAPRODUCT_NUM_PRODUCT_NOT_EXISTS_NO);

        }
        // 校验收货地址
        $address = Address::getAddressList([
            'id'        => $parameters['address_id'],
            'member_id' => Registry::get('jwt_info')->id,
            'from_api'  => $parameters['from_api']
        ]);

        $coupon = null;
        $ali_store = false;
        // 调用1688接口，校验商品库存
        foreach ($num_arr as $key => $value) {
            $sku_id = $sku_id_arr ? $sku_id_arr[$key] : '';
            if (is_null($coupon)) {
                $coupon = new Coupon($parameters['product_id'], $value, Registry::get('jwt_info')->id, $sku_id);
            } else {
                $coupon->setNum($value);
                $coupon->setSkuId($sku_id);
            }

            // 检测本地库存是否有效
            $coupon->checkStore();
            // 调用1688接口，校验商品库存
//            $ali_store = $coupon->checkStoreFromAlibaba();
            if ($key == 0)
                $ali_store = $coupon->checkStoreFromAlibaba(array_sum($num_arr));
            if ($ali_store !== true)
                // 商品不存在于1688接口 将数据库中指定商品的stats调整为0
                $coupon->invalidAlibabaProduct();
            // 更新数据库中 指定商品的库存与最小起订量发生
            $coupon->updateAlibabaProduct();
            // 更新数据库中 指定sku的库存
            $coupon->updateAlibabaProductSku();

            // 事务 更新数据库
            $coupon->updateDb();

            // 用户所购买的商品数量不满足最低起订数
            if (is_string($ali_store))
                throw new AlibabaproductException($ali_store, 400);

            // 扣除redis中的商品库存
            $coupon->decrStoreByProductId();

            if ($ali_store === false)
                throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_INVALID_STORE, AlibabaproductException::ALIBABAPRODUCT_INVALID_STORE_NO);

            /*//总数量
            $parameters['nums'] += $value;
            //获取指定商品信息
            $coupon->getProductInfoFromLocal();
            $productLocal = $coupon->getProductFromLocal();
            //兑换总积分
            $parameters['integral'] += Order::productIntegral($productLocal) * $value;
            //总价
            $parameters['amounts'] += $productLocal['amount'] * $value;
            //单价
            if ($sku_id)
                $parameters['amount'][$sku_id] = $productLocal['amount'];
            else
                $parameters['amount'] = $productLocal['amount'];*/
        }
        $param = $coupon->getIntegralOrderData($parameters['sku_id'], $parameters['num']);
        $parameters = array_merge($parameters, $param);

        $coupon->closeRedis();

        // 增加运费
        $shipping = AlibabaProduct::getShippingFeeByProductIdProvince($parameters['product_id'], $address['data'][0]['province'], $parameters['num']);
        $fee = isset($shipping['real_fee']) ? $shipping['real_fee'] : 0.00;
        $parameters['amounts'] += $fee;
        $parameters['integral'] += $fee * 100;

        //下单
        Order::createOrderByIntegral($parameters);
        return $this->_responseJson($parameters);

    }

    /**
     * @SWG\Post(
     *     path="/v3/order/order2Alibaba",
     *     tags={"订单模块"},
     *     summary="拼团下单,该是接口给服务端使用的，客户端与前端无需调用",
     *     description="
     * sn 必须参数 booking的sn字段，最多允许存在两个不同的sn，用半角逗号间隔",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=false,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="201",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="422",
     *         description="创建失败"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function order2AlibabaAction()
    {
        $parameters = Registry::get('parameters');
        //付款信息订单号 booking中sn
        $sn_s = $parameters['sn'];
        if (empty($sn_s)) {
            throw new BookingException(BookingException::BOOKING_NOT_EXISTS, BookingException::BOOKING_NOT_EXISTS_NO);
        }

        $sn_arr = explode(',', $sn_s);
        $count  = count($sn_arr);


        // 获取支付信息并校验拼团用户是否付款
        // 当booking表中的stats=1且trade_order_sn!=0时，表明第三方支付异步回调已收到，该booking付款信息成功有效，允许参与拼团
        // 因此注释第430行代码
//        $parameters['trade_order_sn'] = 0;
        $parameters['stats'] = 1;

        $list = Booking::getBookingList($parameters);
        if ($count != $list['meta']['total']) {
            throw new BookingException(BookingException::BOOKING_IS_NOT_EXISTS, BookingException::BOOKING_IS_NOT_EXISTS_NO);
        }
        $booking = $list['data'];

        //是否判断 用户第一次拼单，一定失败
        list($jqmem,$k,$order)= Order::firstPinTuan($booking,$sn_arr);
        if(!empty($order)){
            return $this->_responseJson($order);
        }
        //继续原来判断
        if($jqmem==-1&&$k==-1){
            // 判断是否需要机器人参与拼团
            $jqmem = ($count == 1) ? 1 : 0;
            //获胜者
            $k = Order::winMember($booking);
        }

        Registry::get('order_log')->debug('订单数据：' . json_encode([$k, $count]));
        //判断库存并生成插入数据
        $order_data = Order::orderData($booking, $jqmem, $k);

        Registry::get('order_log')->debug('订单数据：' . json_encode($order_data));

        // 拼团商品需要在订单表创建订单
        $order = Order::createOrder($order_data);

        // 给拼团成功和拼团失败的用户发送推送消息
        Order::couponPush($order_data['sn']);

        // 调用1688下单接口
        // 调用1688协议支付接口
        //真正用户拼团成功，到1688下单
        $alibaba_order = [];
        if ($order_data['member_id']) {
            $aliOrder      = [
                'sku_id'     => $order_data['sku_id'],
                'address_id' => $order_data['address_id'],
                'product_id' => $order_data['product_id'],
                'num'        => $order_data['num'],
                'member_id'  => $order_data['member_id'],
                'sn'         => $order_data['sn'],
                'amount'     => $order_data['amountarr'],
            ];
            $alibaba_order = Order::aliCreateOrder($aliOrder);
        }
        $order_data['alibaba_order'] = $alibaba_order;

        $order = Order::handleOrder($order_data);
        return $this->_responseJson($order);
    }

    /**
     * @SWG\Post(
     *     path="/v3/order/balanceOrder",
     *     tags={"订单模块"},
     *     summary="***接口作废***余额购买商品下单",
     *     description="
     * paypassword 必须参数 支付密码
     * product_id 必须参数 商品编号 v3/alibabaproduct/list接口返回的id字段
     * num 必须参数 商品数量,如多样式商品，用','隔开：1,2;必须和sku_id对应
     * address_id 必须参数 收货地址
     * sku_id 非必须参数 sku_id,如多样式商品，用','隔开:4301185405556,4301185405557",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="201",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="422",
     *         description="创建失败"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function balanceOrderAction()
    {
        // 余额买商品
        $parameters = Registry::get('parameters');

        //验证支付密码
        $member=Member::getMemberInfoById(Registry::get('jwt_info')->id);

        if(!isset($member['pay_password'])||empty($member['pay_password'])){
            throw new MemberException(MemberException::MEMBER_PAY_PASSWORD_EMPTY, MemberException::MEMBER_PAY_PASSWORD_EMPTY_NO);
        }
        if (PwdAss::getInstance(8, true)->CheckPassword($parameters['paypassword'], $member['pay_password']) === false)
            throw new MemberException(MemberException::WRONG_PASSWORD, MemberException::WRONG_PASSWORD_NO);

        //校验数量
        if (empty($parameters['num']))
            throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_NUM_NOT_EXISTS, AlibabaproductException::ALIBABAPRODUCT_NUM_NOT_EXISTS_NO);
        //校验数量和sku_id
        $num_arr = explode(',', $parameters['num']);
        $sku_id_arr = explode(',', $parameters['sku_id']);

        if (count($sku_id_arr) > 1 && count($num_arr) != count($sku_id_arr)) {
            throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_NUM_PRODUCT_NOT_EXISTS, AlibabaproductException::ALIBABAPRODUCT_NUM_PRODUCT_NOT_EXISTS_NO);

        }
        // 校验收货地址
        $address = Address::getAddressList([
            'id'        => $parameters['address_id'],
            'member_id' => Registry::get('jwt_info')->id,
            'from_api'  => $parameters['from_api']
        ]);

        $coupon = null;
        $ali_store = false;
        // 调用1688接口，校验商品库存
        foreach ($num_arr as $key => $value) {
            $sku_id = $sku_id_arr ? $sku_id_arr[$key] : '';
            if (is_null($coupon)) {
                $coupon = new Coupon($parameters['product_id'], $value, Registry::get('jwt_info')->id, $sku_id);
            } else {
                $coupon->setNum($value);
                $coupon->setSkuId($sku_id);
            }

            // 检测本地库存是否有效
            $coupon->checkStore();
            // 调用1688接口，校验商品库存
//            $ali_store = $coupon->checkStoreFromAlibaba();
            if ($key == 0)
                $ali_store = $coupon->checkStoreFromAlibaba(array_sum($num_arr));
            if ($ali_store !== true)
                // 商品不存在于1688接口 将数据库中指定商品的stats调整为0
                $coupon->invalidAlibabaProduct();
            // 更新数据库中 指定商品的库存与最小起订量发生
            $coupon->updateAlibabaProduct();
            // 更新数据库中 指定sku的库存
            $coupon->updateAlibabaProductSku();

            // 事务 更新数据库
            $coupon->updateDb();

            // 用户所购买的商品数量不满足最低起订数
            if (is_string($ali_store))
                throw new AlibabaproductException($ali_store, 400);

            // 扣除redis中的商品库存
            $coupon->decrStoreByProductId();

            if ($ali_store === false)
                throw new AlibabaproductException(AlibabaproductException::ALIBABAPRODUCT_INVALID_STORE, AlibabaproductException::ALIBABAPRODUCT_INVALID_STORE_NO);
        }
        $param = $coupon->getIntegralOrderData($parameters['sku_id'], $parameters['num']);
        $parameters = array_merge($parameters, $param);

        $coupon->closeRedis();

        // 增加运费
        $shipping = AlibabaProduct::getShippingFeeByProductIdProvince($parameters['product_id'], $address['data'][0]['province'], $parameters['num']);
        $fee = isset($shipping['real_fee']) ? $shipping['real_fee'] : 0.00;
        $parameters['amounts'] += $fee;
        $parameters['integral'] += $fee * 100;

        //下单
        Order::createOrderByBalance($parameters);
        return $this->_responseJson($param);

    }
}
